package com.etl.mongodb.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation;

import java.text.NumberFormat;
import java.text.ParseException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Locker1995
 * Date: 2018-05-07
 * Time: 11:31 AM
 */
public class ProjectionUtil {



    public static ProjectionOperation getProjection(String str) throws ParseException {
        //获得当前JsonStr的JsonObject
        JSONObject jsonObject = JSONObject.parseObject(str);

        JSONArray jsonArray = jsonObject.getJSONArray("projections");

        ProjectionOperation projection = new ProjectionOperation();

        for(int i = 0;i<jsonArray.size();i++){

            JSONObject object = jsonArray.getJSONObject(i);

            projection = getSubProjection(projection,object);

        }

        return projection;
    }

    /**
     *
     * 获得子 projectionOperation
     *
     * @param projection
     * @param object
     * @return
     * @throws ParseException
     */
    protected static ProjectionOperation getSubProjection(ProjectionOperation projection, JSONObject object) throws ParseException {

        //获得目标字段
        String target = object.getString("target");

        //获得别名
        String alias = object.containsKey("alias")?object.getString("alias"):target;

        //获得当前方法
        String method = object.getString("method");


        if(method != null && (!method.equals(""))){

            JSONArray args = object.getJSONArray("args");
            if(method.equals("plus"))
                if(isNumber(args))
                    projection= projection.and(target).plus(NumberFormat.getInstance().parse(args.getString(0))).as(alias);
                else
                    projection = projection.and(target).plus(args.getString(0)).as(alias);

            if(method.equals("multiply"))
                if(isNumber(args))
                    projection= projection.and(target).multiply(NumberFormat.getInstance().parse(args.getString(0))).as(alias);
                else
                    projection = projection.and(target).multiply(args.getString(0)).as(alias);

            if(method.equals("divide"))
                if(isNumber(args))
                    projection= projection.and(target).divide(NumberFormat.getInstance().parse(args.getString(0))).as(alias);
                else
                    projection = projection.and(target).divide(args.getString(0)).as(alias);

            if(method.equals("minus"))
                if(isNumber(args))
                    projection= projection.and(target).minus(NumberFormat.getInstance().parse(args.getString(0))).as(alias);
                else
                    projection = projection.and(target).minus(args.getString(0)).as(alias);

            if(method.equals("substring"))
                if(args.size()==1)
                    projection = projection.and(target).substring(args.getInteger(0)).as(alias);
                else
                    projection = projection.and(target).substring(args.getInteger(0),args.getInteger(1)).as(alias);

            if(method.equals("concat"))
                projection = projection.and(target).concat(args.toArray()).as(alias);

            return projection;
        }
        else
            return  projection.and(target).as(alias);

    }


    /**
     *
     * 判断第一个参数是否是 数字类型
     *
     * @param args
     * @return
     */
    protected static boolean isNumber(JSONArray args){

        try {

            NumberFormat.getInstance().parse(args.getString(0));

            return true;
        } catch (ParseException e) {
            return false;
        }
    }

}
